#include "stdafx.h"
#include <time.h>
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include "shlwapi.h"
#include "shlobj.h"
#include "LogFile.h"
#include "Log.h"
using namespace std;

#pragma comment( lib, "shlwapi.lib" )
#pragma comment( lib, "ws2_32.lib" )

namespace Zen{namespace utility{

#ifdef SIMPLE_LOG
simple_log _glog;
#endif

// log file create time, update on application startup
static time_t gLogTime = -1;

/*
 * open the log file
 *
 * create the log dir if non-exist, 
 * get the log time at the first time, 
 * compose the log file name
 *
 */
bool simple_log::OpenLog()
{
	if (NULL == gLogFile)
		gLogFile = new LogFile();

	if (NULL == gLogFile)
		return false;

	// get working directory
	char dirPath[MAX_PATH] = {0};
	::GetModuleFileNameA(NULL,dirPath,sizeof(dirPath));
	char * pTmp = strrchr(dirPath, '\\');
	if (NULL != pTmp)
		*pTmp = '\0';

	// append the log dir string
	strcat_s(dirPath, "\\logs");

	// check the log dir
	if (!PathFileExistsA(dirPath) && ERROR_SUCCESS != SHCreateDirectoryExA(NULL,dirPath,NULL))
		return false;

	// get log time at the first time
	if (gLogTime == -1) {
		time(&gLogTime);
	}

	// increase the log index each time
	gLogIndex++;

	// compose the log file path
	char temp[24];
	strftime(temp, 20, "%Y%m%d-%H%M%S", localtime(&gLogTime));
	if (name_.empty())
		_snprintf_s(gLogName, sizeof(gLogName), "%s\\%s-%d.log", dirPath, temp, gLogIndex);
	else
		_snprintf_s(gLogName, sizeof(gLogName), "%s\\%s-%s-%d.log", dirPath, temp, name_.c_str(), gLogIndex);

	if (!gLogFile->open(gLogName))
		return false;

	return true;
}

/*
 * close and flush the log file, and free all resources
 */
void simple_log::CloseLog()
{
	if (NULL != gLogFile) {
		gLogFile->flush();
		gLogFile->close();
		delete gLogFile;
		gLogFile = NULL;
	}
}

/*
 * get current log file name, include the full path
 */
const char * simple_log::GetLogName()
{
	return gLogName;
}

/*
 * get the size of current log file, return 0 if not yet open
 */
int simple_log::GetLogSize()
{
	if (NULL != gLogFile)
		return gLogFile->size();
	return 0;
}

/*
 * print string into log
 *
 * the string will be logged into file, and then printed out
 */
void simple_log::operator()(const char *fmt, ...)
{
	char str[1024];
	int size;

    va_list args;
    va_start(args, fmt);
	size = _vsnprintf_s(str, sizeof(str), fmt, args);
	va_end(args);

	if (gLogFile != NULL)
		gLogFile->log(str);

	strncat_s(str, sizeof(str), "\r\n", 2);
	printf(str);

	if (GetLogSize() >= LOG_MAX_SIZE) 
	{
		//PrintLog("current log file size: %d large than %d, (%s)\n", GetLogSize(), LOG_MAX_SIZE, GetLogName());
		CloseLog();
		OpenLog();
		(*(this))("create new log file(%s)\n", GetLogName());
	}
}

simple_log::simple_log( const string& name )
	:name_(name)
	,gLogFile(NULL)
	,gLogIndex(-1)
{
	OpenLog();
}

simple_log::~simple_log()
{
	CloseLog();
}

LogFile* simple_log::GetLogFile()
{
	return gLogFile;
}

}}
